package entities.concept;

import java.util.HashSet;
import java.util.Set;

import entities.KBEntity;
import entities.role.Role;

public abstract class QuantifiedConcept extends Concept {
	protected final Role role;
	protected final Concept filler;

	protected QuantifiedConcept(Role role, Concept filler) {
		this.role = role;
		this.filler = filler;
	}

	public Concept getFiller() {
		return this.filler;
	}

	public Role getRole() {
		return this.role;
	}

	@Override
	public abstract Concept getPrimeCopy();

	@Override
	public abstract String toSerializedString();

	@Override
	public Set<Role> extractFeatures() {
		return this.filler.extractFeatures();
	}

	@Override
	public Set<Role> extractRoles() {
		Set<Role> fs = new HashSet<Role>();
		fs.add(role);
		fs.addAll(this.filler.extractRoles());
		return fs;
	}

	@Override
	public Set<String> extractConstants() {
		Set<String> ks = new HashSet<String>();
		ks.addAll(this.filler.extractConstants());
		return ks;
	}

	@Override
	public Set<AtomicConcept> extracAtomicConcepts() {
		Set<AtomicConcept> cs = new HashSet<AtomicConcept>();
		cs.addAll(this.filler.extracAtomicConcepts());
		return cs;
	}
	
	@Override 
	public Set<KBEntity> extractSig(){
		Set<KBEntity> sig = new HashSet<KBEntity>();
		sig.add(role);
		sig.addAll(this.filler.extractSig());
		return sig;
	}

	@Override
	public boolean isParameterized() {
		return this.filler.isParameterized();
	}

	@Override
	public Concept makeParameterized() {
		if (this instanceof UniversalConcept) {
			return new UniversalConcept(this.role,
					this.filler.makeParameterized());
		} else if (this instanceof ExistsConcept) {
			return new ExistsConcept(this.role, this.filler.makeParameterized());
		} else {
			return this;
		}

	}

	@Override
	public Concept initParameters(Role f, String v) {
		if (this instanceof UniversalConcept) {
			return new UniversalConcept(this.role, this.filler.initParameters(
					f, v));
		} else if (this instanceof ExistsConcept) {
			return new ExistsConcept(this.role,
					this.filler.initParameters(f, v));
		} else {
			return this;
		}
	}

}
